package com.micro.ai.files.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.micro.ai.commons.exception.BusinessException;
import com.micro.ai.files.entity.FileTag;
import com.micro.ai.files.mapper.FileTagMapper;
import com.micro.ai.files.service.FileTagService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 文件标签服务实现
 * 
 * @author micro-ai
 * @since 0.0.1
 */
@Slf4j
@Service
public class FileTagServiceImpl extends ServiceImpl<FileTagMapper, FileTag> implements FileTagService {

    @Override
    @Transactional(rollbackFor = Exception.class)
    public FileTag create(FileTag tag) {
        if (tag == null) {
            throw new BusinessException("F0000", "标签信息不能为空");
        }
        
        if (!StringUtils.hasText(tag.getTenantId())) {
            throw new BusinessException("F0000", "租户ID不能为空");
        }
        
        if (!StringUtils.hasText(tag.getTagName())) {
            throw new BusinessException("F0000", "标签名称不能为空");
        }
        
        // 检查同一租户下标签名称是否重复
        FileTag existing = getByTagName(tag.getTenantId(), tag.getTagName());
        if (existing != null) {
            // 如果已存在，增加使用次数
            incrementUsageCount(existing.getId());
            return existing;
        }
        
        if (tag.getTagColor() == null) {
            tag.setTagColor("#1890ff");
        }
        if (tag.getUsageCount() == null) {
            tag.setUsageCount(1);
        }
        
        tag.setCreatedAt(LocalDateTime.now());
        tag.setUpdatedAt(LocalDateTime.now());
        
        boolean success = this.save(tag);
        if (!success) {
            throw new BusinessException("F0003", "创建标签失败");
        }
        
        log.info("创建标签成功: tagId={}, tagName={}", tag.getId(), tag.getTagName());
        return tag;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public FileTag update(String id, FileTag tag) {
        if (!StringUtils.hasText(id)) {
            throw new BusinessException("F0000", "标签ID不能为空");
        }
        if (tag == null) {
            throw new BusinessException("F0000", "标签信息不能为空");
        }
        
        FileTag existing = this.getById(id);
        if (existing == null) {
            throw new BusinessException("F0002", "标签不存在: " + id);
        }
        
        tag.setId(id);
        tag.setUpdatedAt(LocalDateTime.now());
        
        boolean success = this.updateById(tag);
        if (!success) {
            throw new BusinessException("F0003", "更新标签失败");
        }
        
        log.info("更新标签成功: tagId={}", id);
        return tag;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(String id) {
        if (!StringUtils.hasText(id)) {
            throw new BusinessException("F0000", "标签ID不能为空");
        }
        
        FileTag tag = this.getById(id);
        if (tag == null) {
            throw new BusinessException("F0002", "标签不存在: " + id);
        }
        
        boolean success = this.removeById(id);
        if (!success) {
            throw new BusinessException("F0003", "删除标签失败");
        }
        
        log.info("删除标签成功: tagId={}, tagName={}", id, tag.getTagName());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void incrementUsageCount(String id) {
        FileTag tag = this.getById(id);
        if (tag != null) {
            tag.setUsageCount((tag.getUsageCount() == null ? 0 : tag.getUsageCount()) + 1);
            tag.setUpdatedAt(LocalDateTime.now());
            this.updateById(tag);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void decrementUsageCount(String id) {
        FileTag tag = this.getById(id);
        if (tag != null) {
            int count = (tag.getUsageCount() == null ? 0 : tag.getUsageCount()) - 1;
            if (count < 0) {
                count = 0;
            }
            tag.setUsageCount(count);
            tag.setUpdatedAt(LocalDateTime.now());
            this.updateById(tag);
        }
    }

    @Override
    public Page<FileTag> pageQuery(int pageNum, int pageSize, String tenantId, String keyword) {
        if (pageNum < 1) {
            pageNum = 1;
        }
        if (pageSize < 1 || pageSize > 100) {
            pageSize = 20;
        }
        
        Page<FileTag> page = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<FileTag> query = new LambdaQueryWrapper<>();
        
        if (StringUtils.hasText(tenantId)) {
            query.eq(FileTag::getTenantId, tenantId);
        }
        if (StringUtils.hasText(keyword)) {
            query.like(FileTag::getTagName, keyword);
        }
        
        query.orderByDesc(FileTag::getUsageCount);
        query.orderByDesc(FileTag::getCreatedAt);
        
        return this.page(page, query);
    }

    @Override
    public List<FileTag> listAll(String tenantId) {
        LambdaQueryWrapper<FileTag> query = new LambdaQueryWrapper<>();
        query.eq(FileTag::getTenantId, tenantId)
             .orderByDesc(FileTag::getUsageCount)
             .orderByDesc(FileTag::getCreatedAt);
        
        return this.list(query);
    }

    @Override
    public FileTag getByTagName(String tenantId, String tagName) {
        LambdaQueryWrapper<FileTag> query = new LambdaQueryWrapper<>();
        query.eq(FileTag::getTenantId, tenantId)
             .eq(FileTag::getTagName, tagName);
        
        return this.getOne(query);
    }
}

